/*************************************************************************
 *
 * stavove funkce menu
 * 
 * (c) Ales Povalac, alpov@alpov.net, http://www.alpov.net/
 * 
 *************************************************************************
 *
 * $Id: menu_stfn.c 117 2007-01-22 15:49:41Z Ales $
 * 
 *************************************************************************/         

#include <inttypes.h>
#include <string.h>
#include <avr/pgmspace.h>
#include "../avrx/avrx.h"
#include "../avrx/AvrXFifo.h"
#include "hw.h"
#include "button.h"
#include "menu.h"
#include "menu_stfn.h"
#include "menu_lcd.h"
#include "data.h"
#include "datetime.h"
#include "serial.h"

static signed char *value;
static unsigned long *clock;
static signed char value_min, value_max;
static unsigned char value_overlap = 0;
static unsigned char substate = 0;

static char PROGMEM dt_min[6] = {0, 1, 0, 0, 0, 0};
static char PROGMEM dt_max[6] = {127, 12, 130, 23, 59, 59};


/*************************************************************************
 * stavova funkce - zmena senzoru nebo infa na hlavni obrazovce
 *************************************************************************/ 
unsigned char MenuChangeMain(unsigned char key, unsigned char state)
{
    value_min = 0;
    value_overlap = 1;

#if (DISPLAY == 1602)
    if (key & KEY_SET) {
        value = &eedata.info_index;
        value_max = 1;
        key |= KEY_PLUS;
    } else {
        value = &eedata.sensor_index;
        value_max = AvrXReadEEProm(&desc.sensor_count) - 1;
    }

#elif (DISPLAY == 2004)
    if (key & KEY_SET)
        value = &eedata.sensor_index2;
    else
        value = &eedata.sensor_index;

    value_max = AvrXReadEEProm(&desc.sensor_count) - 1;
    
#endif

    key &= (KEY_PLUS | KEY_MINUS);

    return MenuChangeValue(key, state);
}


/*************************************************************************
 * stavova funkce - uprava obecne hodnoty
 *************************************************************************/ 
unsigned char MenuChangeValue(unsigned char key, unsigned char state)
{
    if (key == KEY_PLUS) {
        if (*value < value_max)
            (*value)++;
        else if (value_overlap)
            (*value) = value_min;
            
    } else if (key == KEY_MINUS) {
        if (*value > value_min)
            (*value)--;
        else if (value_overlap)
            (*value) = value_max;

    }
    
    // specialni pripad - kontrast ihned ukazovat
    if (value == &eedata.contrast)
        LcdSetContrast(eedata.contrast);
    
    return state;
}


/*************************************************************************
 * stavova funkce - uprava hodnoty hodin
 *************************************************************************/ 
unsigned char MenuChangeClock(unsigned char key, unsigned char state)
{
    unsigned char dt[6];
    
    decode_date(*clock, &dt[2], &dt[1], &dt[0]);
    decode_time(*clock, &dt[3], &dt[4], &dt[5]);

    if (key == KEY_PLUS) {
        if (dt[substate] < pgm_read_byte(&dt_max[substate]))
            dt[substate]++;
            
    } else if (key == KEY_MINUS) {
        if (dt[substate] > pgm_read_byte(&dt_min[substate]))
            dt[substate]--;

    }
    
    *clock = encode_datetime(dt[2], dt[1], dt[0], dt[3], dt[4], 0);
    
    return state;
}


/*************************************************************************
 * stavova funkce - posun
 *************************************************************************/ 
unsigned char MenuEditShift(unsigned char key, unsigned char state)
{
    if (state == ST_SHIFT) {
        BeginEditing();
        substate = 0;
        value = &rwdata.shift;
        value_min = -MENU_MAX_SHIFT;
        value_max = MENU_MAX_SHIFT;
        value_overlap = 0;
        return ST_SHIFT_EDIT;
    }
    if (key == KEY_FN) {
        CancelEditing();
        return ST_SHIFT;
    }

    switch (++substate) {
        case 1: {
            value = &rwdata.shift_length;
            value_min = 0;
            value_max = 30;
            return ST_SHIFT_EDIT;
        }
        case 2: {
            EndEditing(ITEM_SHIFT);
            return ST_SHIFT;
        }
        default:
            return ST_ERROR;
    }
}


/*************************************************************************
 * stavova funkce - rezim
 *************************************************************************/ 
unsigned char MenuEditMode(unsigned char key, unsigned char state)
{
    if (state == ST_MODE) {
        BeginEditing();
        value = &rwdata.mode;
        value_min = 0;
        value_max = AvrXReadEEProm(&desc.mode_count) - 1;
        value_overlap = 1;
        return ST_MODE_EDIT;
    }
    if (key == KEY_FN) {
        CancelEditing();
        return ST_MODE;
    }

    EndEditing(ITEM_MODE);
    return ST_MODE;
}


/*************************************************************************
 * stavova funkce - hodiny realneho casu
 *************************************************************************/ 
unsigned char MenuEditRtc(unsigned char key, unsigned char state)
{
    if (state == ST_RTC) {
        BeginEditing(); // FIXME nezalohuje NOW
        substate = 0;
        clock = &now;
        return ST_RTC_EDIT;
    }
    if (key == KEY_FN) {
        CancelEditing(); 
        return ST_RTC;
    }

    switch (++substate) {
        case 1:
        case 2:
        case 3:
        case 4: {
            return ST_RTC_EDIT;
        }
        case 5: {
            EndEditing(ITEM_RTC);
            return ST_RTC;
        }
        default:
            return ST_ERROR;
    }
}


/*************************************************************************
 * stavova funkce - prepnuti rezimu
 *************************************************************************/ 
unsigned char MenuEditSwitch(unsigned char key, unsigned char state)
{
    if (state == ST_SWITCH) {
        BeginEditing();
        substate = 0;
        value = &rwdata.sw_mode;
        value_min = -1;
        value_max = AvrXReadEEProm(&desc.mode_count) - 1;
        value_overlap = 1;
        return ST_SWITCH_EDIT_M;
    }
    if (key == KEY_FN) {
        CancelEditing(); 
        return ST_SWITCH;
    }
    
    if (state == ST_SWITCH_EDIT_M) {
        if (rwdata.sw_mode < 0) {
            EndEditing(ITEM_SWITCH);
            return ST_SWITCH;
        } else {
            substate = 0;
            clock = &rwdata.sw_datetime;
            return ST_SWITCH_EDIT_C;
        }

    } else {  // ST_SWITCH_MODE_C
        switch (++substate) {
            case 1:
            case 2:
            case 3:
            case 4: {
                return ST_SWITCH_EDIT_C;
            }
            case 5: {
                EndEditing(ITEM_SWITCH);
                return ST_SWITCH;
            }
            default:
                return ST_ERROR;
        }

    }
}


/*************************************************************************
 * stavova funkce - konfigurace jednotky
 *************************************************************************/ 
unsigned char MenuEditConfig(unsigned char key, unsigned char state)
{
    if (state == ST_CONFIG) {
        substate = 0;
        value = &eedata.addr;
        value_min = 0;
        value_max = 127;
        value_overlap = 1;
        return ST_CONFIG_EDIT;
    }
    if (key == KEY_FN) {
        ReadEepromData();
        return ST_CONFIG;
    }

    switch (++substate) {
        case 1: {
            value = &eedata.contrast;
            value_min = LCD_CONTRAST_MIN;
            value_max = LCD_CONTRAST_MAX;
            value_overlap = 0;
            return ST_CONFIG_EDIT;
        }
        case 2: {
            value = &eedata.reset;
            value_min = 0;
            value_max = 1;
            value_overlap = 1;
            return ST_CONFIG_EDIT;
        }
        case 3: {
            if (eedata.reset)
                AvrXHalt();
            
            WriteEepromData();
            
            return ST_CONFIG;
        }
        default:
            return ST_ERROR;
    }
}

